#!/usr/bin/env python3
import argparse, json, os, sys, time, subprocess
from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime
from tqdm import tqdm

def install_and_test(pkg: str, out_dir: str):
    ts = datetime.utcnow().isoformat(timespec='seconds')
    log_file = os.path.join(out_dir, f"{pkg}_{ts.replace(':', '')}.json")
    log = {
        "package": pkg,
        "version": None,
        "install_success": False,
        "test_success": False,
        "test_cases": {},
        "log": "",
        "timestamp": ts,
        "duration_s": 0
    }
    start = time.time()
    try:
        subprocess.check_call([sys.executable, "-m", "pip", "install", pkg],
                              stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        log["install_success"] = True
        meta = subprocess.check_output([sys.executable, "-m", "pip", "show", pkg],
                                       text=True)
        log["version"] = [line.split(":")[1].strip() for line in meta.splitlines()
                          if line.startswith("Version:")][0]
        __import__(pkg)
        log["test_success"] = True
        log["test_cases"]["import"] = "pass"
    except Exception as e:
        log["log"] = str(e)
    log["duration_s"] = round(time.time() - start, 2)

    os.makedirs(out_dir, exist_ok=True)
    with open(log_file, "w", encoding="utf-8") as f:
        json.dump(log, f, indent=2, ensure_ascii=False)
    return log

def main():
    parser = argparse.ArgumentParser(description="OpenCloudOS 批量并发 PyPI 验证工具")
    parser.add_argument("pkg_list", help="文本文件，每行一个包名")
    parser.add_argument("-j", "--jobs", type=int, default=3, help="并发数")
    parser.add_argument("-o", "--out", default="logs", help="输出目录")
    args = parser.parse_args()

    with open(args.pkg_list, encoding="utf-8") as f:
        pkgs = [line.strip() for line in f if line.strip()]

    print(f"待测包数: {len(pkgs)}  并发数: {args.jobs}")
    ok = 0
    with ThreadPoolExecutor(max_workers=args.jobs) as pool:
        future_map = {pool.submit(install_and_test, p, args.out): p for p in pkgs}
        for f in tqdm(as_completed(future_map), total=len(pkgs), desc="Testing"):
            res = f.result()
            if res["install_success"] and res["test_success"]:
                ok += 1
    print(f"全部完成！成功 {ok}/{len(pkgs)}  日志目录: {args.out}")

if __name__ == "__main__":
    main()